#include <gtk/gtk.h>

#include <stdlib.h>

#include "../core.h"
#include "../config.h"
#include "../loaders.h"
#include "confwin.h"
#include "logwin.h"

GtkWidget *logwin_item;
GtkWidget *load_dialog;
GtkListStore *gameslist;

char *loadfile = NULL;

typedef enum
{
    COL_NAME,
    COL_FILENAME
} ListCol;

void run_file()
{
    g_thread_create((void*)&core_start, loadfile, FALSE, NULL);
}

G_MODULE_EXPORT void menu_uncheck_logwin()
{
    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(logwin_item), FALSE);
}

G_MODULE_EXPORT void file_load_select()
{
    if (gtk_dialog_run(GTK_DIALOG(load_dialog)) == GTK_RESPONSE_ACCEPT)
    {
        char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(load_dialog));
        if (loadfile)
            loadfile = realloc(loadfile, strlen(filename) + 1);
        else
            loadfile = malloc(strlen(filename) + 1);
        loadfile[0] = '\0';
        strcpy(loadfile, filename);
        g_free(filename);
        gtk_widget_hide(load_dialog);
        run_file();
    }
    else
        gtk_widget_hide(load_dialog);
}

void gameslist_sync()
{
    char *path;
    IsoFileNode root;
    IsoFileNode *node;
    GtkTreeIter iter;

    gdk_threads_leave();

    path = conf_load("isopath");
    if (!path) {
        gdk_threads_enter();
        return;
    }
    root = load_findFiles(path);
    conf_free(path);

    gdk_threads_enter();

    gtk_list_store_clear(gameslist);

    node = &root;
    while (node->next)
    {
        node = node->next;
        gtk_list_store_append(gameslist, &iter);
        gtk_list_store_set(gameslist, &iter, COL_NAME, node->info.title, -1);
        gtk_list_store_set(gameslist, &iter, COL_FILENAME, node->filename, -1);
    }

    gdk_threads_leave();
    load_freeFiles(&root);
    gdk_threads_enter();
}

G_MODULE_EXPORT void gameslist_run(GtkTreeView *tree_view, GtkTreePath *path)
{
    gchararray filename;
    GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
    GtkTreeIter iter;
    gtk_tree_model_get_iter(model, &iter, path);
    gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
    loadfile = malloc(strlen(filename) + 1);
    loadfile[0] = '\0';
    strcpy(loadfile, filename);
    run_file();
}

s32 main(s32 argc, char *argv[])
{
    GtkBuilder *builder;

    GtkWidget *mainwin;

    /* init logging mutex */
    logInitTh();

    /* inits GTK+ */
    g_thread_init(NULL);
    gdk_threads_init();

    gtk_init(&argc, &argv);

    /* loads the glade file */
    builder = gtk_builder_new();
    gtk_builder_add_from_file(builder, "gui.glade", NULL);

    /* gets the widgets from the glade file & creates what can't be done with glade (like callbacks to local functions) */
    mainwin = GTK_WIDGET(gtk_builder_get_object(builder, "mainwin"));
    logwin_item = GTK_WIDGET(gtk_builder_get_object(builder, "logwin_item"));
    load_dialog = GTK_WIDGET(gtk_builder_get_object(builder, "load_dialog"));
    gameslist = GTK_LIST_STORE(gtk_builder_get_object(builder, "gameslist"));

    /* inits the logging window */
    logwin_init(builder);

    /* inits the config window */
    confwin_init(builder);

    /* connects the signals written in glade */
    gtk_builder_connect_signals(builder, NULL);

    /* frees the builder */
    g_object_unref(G_OBJECT(builder));

    gdk_threads_enter();
    gameslist_sync();
    gdk_threads_leave();

    /* shows all the widgets */
    gtk_widget_show_all(mainwin);

    /* run the window in another thread */
    gdk_threads_enter();
    gtk_main();
    gdk_threads_leave();

    free(loadfile);

    logFreeTh();

    return 0;
}

